package com.juyu.miliao.api.handler;

import com.juyu.miliao.api.dao.elasticsearch.FindDynamicElasticsearch;
import com.juyu.miliao.api.dao.mysql.FindDynamicInfoDao;
import com.juyu.miliao.api.dao.mysql.SuspendDao;
import com.juyu.miliao.api.dao.mysql.UserCountDao;
import com.juyu.miliao.api.dao.mysql.UserInfoDao;
import com.juyu.miliao.api.domain.FindDynamicInfo;
import com.juyu.miliao.api.domain.Suspend;
import com.juyu.miliao.api.domain.User;
import com.juyu.miliao.api.domain.vo.FindDynamicDetailVO;
import com.juyu.miliao.api.rabbitMQ.BillDetailIntegralMq;
import com.juyu.miliao.common.builder.BillDetailIntegralMqMessageBuilder;
import com.juyu.miliao.common.constant.*;
import com.juyu.miliao.common.domain.dto.BillDetailIntegralDTO;
import com.juyu.miliao.common.domain.dto.SystemRewardsAndPunishmentDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.concurrent.TimeUnit;


/**
 * @author xuanqicheng
 */
@Component
@Slf4j
public class IntegralRewardsAndPunishmentsHandler {

    @Autowired
    private UserCountDao userCountDao;

    @Autowired
    private BillDetailIntegralMq billDetailIntegralMq;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FindDynamicElasticsearch findDynamicElasticsearch;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private SuspendDao suspendDao;

    @Autowired
    private FindDynamicInfoDao findDynamicInfoDao;

    /**
     * 通话时间大于3分钟，增加积分
     *
     * @param userId
     * @param minute
     */
    public void aSigleCallLastsMoreThanThreeMinutes(long userId, int minute) {
        boolean b = checkIsHost(userId);
        if (!b) {
            return;
        }
        if (minute > 3) {
            int integralValue = IntegralRewardsAndPunishmentsType.A_SINGLE_CALL_LASTS_MORE_THAN_THREE_MINUTES
                    .getIntegralValue();
            int flag = userCountDao.updateIntegralSum(userId, integralValue);
            if (flag > 0) {
                //添加账单
                BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, IntegralRewardsAndPunishmentsType
                        .A_SINGLE_CALL_LASTS_MORE_THAN_THREE_MINUTES);

                billDetailIntegralMq.getBillDetailIntegralMq(obj);
            }
        }
    }

    /**
     * 单条点赞超过20
     */
    public void signleDynamicPointPraisOver20(int dynamicId) {
        FindDynamicInfo findDynamicInfo=findDynamicInfoDao.getFindDynamicByFindId(dynamicId);

        long maxNum = SignleDynamicPointPraisOver20Constant.MAX_NUM;

        String redisKey = SignleDynamicPointPraisOver20Constant
                .SIGNLE_DYNAMIC_POINT_PRAIS_ADD_INTEGRAL_DYNAMIC_ID_REDIS_KEY;
        boolean bl = stringRedisTemplate.opsForSet().isMember(redisKey, dynamicId + "");
        if (!bl) {
            String key = SignleDynamicPointPraisOver20Constant.getSignleDynamicPointPraisByNumber(dynamicId);
            long number = stringRedisTemplate.opsForValue().increment(key, 1);
            log.info("动态[{}]点赞次数[{}]",dynamicId,number);
            if (number == maxNum) {

                int integralValue = IntegralRewardsAndPunishmentsType
                        .SINGLE_DYNAMIC_POINT_PRAISE_OVER_20.getIntegralValue();

                int flag = userCountDao.updateIntegralSum(findDynamicInfo.getUserId(), integralValue);
                if (flag == 1) {
                    log.info("点赞动态[{}],用户[{}]添加积分",dynamicId,findDynamicInfo.getUserId());
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(findDynamicInfo.getUserId(), IntegralRewardsAndPunishmentsType
                            .SINGLE_DYNAMIC_POINT_PRAISE_OVER_20);

                    billDetailIntegralMq.getBillDetailIntegralMq(obj);

                    stringRedisTemplate.opsForSet().add(redisKey, dynamicId + "");

                    stringRedisTemplate.expire(key, 365, TimeUnit.DAYS);
                }

            }
        }

    }

    /**
     * 单条动态评论人数查过10个
     *
     * @param dynamicId
     * @param userId 动态拥有者
     * @param commentOrReplyUserId  评论或回复的人
     */
    public void singleDynamicCommentAndReplyOver10People(int dynamicId,long userId,
                                                         long commentOrReplyUserId) {

        long maxValue = SingleDynamicCommentAndReplyOver10PeopleConstant.MAX_VALUE;

        String redisKey = SingleDynamicCommentAndReplyOver10PeopleConstant
                .getDynamicCommentAndReplyExistUserIdByDynamicIdRedisKey(dynamicId);

        boolean bl = stringRedisTemplate.opsForSet().isMember(redisKey, commentOrReplyUserId + "");
        if (!bl) {
            String key = SingleDynamicCommentAndReplyOver10PeopleConstant
                    .getDynamicCommentAndReplyNumByDynamicIdRedisKey(dynamicId);
            long number = stringRedisTemplate.opsForValue().increment(key, 1);
            if (number == maxValue) {

                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .SINGLE_DYNAMIC_COMMENT_AND_REPLY_OVER_10_PEOPLE;

                int integralValue = type.getIntegralValue();

                int flag = userCountDao.updateIntegralSum(userId, integralValue);
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                    stringRedisTemplate.expire(key, 365, TimeUnit.DAYS);
                }

            }
            stringRedisTemplate.opsForSet().add(redisKey, commentOrReplyUserId + "");
        }
    }

    /**
     * 分享自己的动态
     *
     * @param findId
     * @param userId
     * @throws IOException
     */
    public void shareMySelfOneDynamic(int findId, long userId) throws IOException {
        boolean bl = checkIsHost(userId);
        if (!bl) {
            return;
        }
        FindDynamicDetailVO findDynamicDetailVO = findDynamicElasticsearch.getFindDynamicInfoByFindId(findId);
        if (findDynamicDetailVO != null) {
            if (userId == findDynamicDetailVO.getUserId().longValue()) {
                String key = ShareMySelfOneDynamicConstant.getShareMyselfOneDyanmicByUseridRedisKey(userId);
                if (!stringRedisTemplate.hasKey(key)) {

                    IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                            .SHARE_MYSELF_ONE_DYNAMIC;
                    int integralValue = type.getIntegralValue();
                    int flag = userCountDao.updateIntegralSum(userId, integralValue);
                    if (flag == 1) {
                        stringRedisTemplate.opsForValue().increment(key, 1);
                        BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                        billDetailIntegralMq.getBillDetailIntegralMq(obj);
                        stringRedisTemplate.expire(key, 1, TimeUnit.DAYS);
                    }

                }
            }
        }

    }

    /**
     * 上传图片
     *
     * @param userId
     * @param num
     */
    public void uploadPic(long userId, int num) {
        boolean b = checkIsHost(userId);
        if (!b) {
            return;
        }
        long maxValue = UploadPicAndVideoConstant.PIC_MAX_VALUE;
        String extisKey = UploadPicAndVideoConstant.getHostUserUploadPicExistUseridRedisKey();
        boolean bl = stringRedisTemplate.opsForSet().isMember(extisKey, userId + "");
        if (!bl) {
            String key = UploadPicAndVideoConstant.getHostUserUploadPicReidsKey(userId);
            long target = stringRedisTemplate.opsForValue().increment(key, num);
            if (target >= maxValue) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType.UPLOAD_PIC;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    stringRedisTemplate.opsForSet().add(extisKey, userId + "");
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                    stringRedisTemplate.expire(key, 1, TimeUnit.DAYS);
                }
            }
        }

    }

    /**
     * 上传视频
     *
     * @param userId
     */
    public void uploadVideo(long userId) {
        boolean bl = checkIsHost(userId);
        if (!bl) {
            return;
        }
        String key = UploadPicAndVideoConstant.getHostUserUploadVideoRedisKey(userId);
        if (!stringRedisTemplate.hasKey(key)) {
            IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType.UPLOAD_VIDEO;
            int integralValue = type.getIntegralValue();
            int flag = userCountDao.updateIntegralSum(userId, integralValue);
            if (flag == 1) {
                BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                billDetailIntegralMq.getBillDetailIntegralMq(obj);
                stringRedisTemplate.opsForValue().increment(key, 1);
                stringRedisTemplate.expire(key, 1, TimeUnit.DAYS);
            }


        }
    }

    /**
     * 举报
     *
     * @param userId
     * @return
     */
    public void reported(long userId) {
        if (!checkIsHost(userId)) {
            return;
        }
        long maxValue = IntegralReportedConstant.MAX_NUM;
        String existKey = IntegralReportedConstant.getIntegralReportedExistUserRedisKey();
        boolean bl = stringRedisTemplate.opsForSet().isMember(existKey, userId + "");
        if (!bl) {
            String key = IntegralReportedConstant.getIntegralReportedUserRedisKey(userId);
            long num = stringRedisTemplate.opsForValue().increment(key, 1);
            if (num <= maxValue) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType.REPORTED;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                }
                if (num == maxValue) {
                    stringRedisTemplate.opsForSet().add(existKey, userId + "");
                    stringRedisTemplate.expire(existKey, 1, TimeUnit.DAYS);
                    stringRedisTemplate.expire(key, 1, TimeUnit.DAYS);
                }
            }
        }

    }

    /**
     * 钻石增加积分
     *
     * @param userId
     * @param diamonds
     */
    public void diamondsForIntegralBy100(long userId, double diamonds) {
        if (!checkIsHost(userId)) {
            return;
        }
        double maxValue = DiamondsForIntegralBy100RedisKey.MAX_VALUE;

        String key = DiamondsForIntegralBy100RedisKey.getDiamondsForIntegralBy100UserIdKey(userId);

        double num = stringRedisTemplate.opsForValue().increment(key, diamonds);

        if (num >= maxValue) {
            int size = (int) (num / maxValue);
            if (size >= 1) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .DIAMONDS_FOR_INTEGRAL_BY_100;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue() * size);
                if (flag == 1) {
                    BillDetailIntegralMqMessageBuilder mqMessageBuilder = new BillDetailIntegralMqMessageBuilder();
                    BillDetailIntegralDTO billDetailIntegralDTO = mqMessageBuilder.userId(userId)
                            .integralRewardsPunishmentsType(type)
                            .integralValue(type.getIntegralValue() * size)
                            .createDate(LocalDate.now(ZoneOffset.of("+8")))
                            .createTime(LocalDateTime.now(ZoneOffset.of("+8")))
                            .build();
                    billDetailIntegralMq.getBillDetailIntegralMq(billDetailIntegralDTO);
                    stringRedisTemplate.opsForValue().increment(key, -maxValue * size);
                }
            }

        }
    }


    /**
     * 封号
     */
    public void suspend(long userId) {
        if (!checkIsHost(userId)) {
            return;
        }
        Suspend suspend = suspendDao.getSuspendsByUserId(userId);
        if (suspend != null) {
            int suspendType = suspend.getType();

            if (suspendType == SuspendType.ONE_DAY.getCode()) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .KICK_ONE_DAY;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                }

            } else if (suspendType == SuspendType.ONE_WEEK.getCode()) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .KICK_ONE_WEEK;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                }

            } else if (suspendType == SuspendType.ONE_MONTH.getCode()) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .KICK_ONE_MONTH;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                }
            } else if (suspendType == SuspendType.FOREVER.getCode()) {
                IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                        .KICK_FOREVER;
                int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                if (flag == 1) {
                    BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                    billDetailIntegralMq.getBillDetailIntegralMq(obj);
                }

            }
        }

    }

    /**
     * 成功发布动态
     *
     * @param dynamicId
     */
    public void successReleaseOfADynamic(int dynamicId) {

        FindDynamicInfo findDynamicInfo = findDynamicInfoDao.getFindDynamicByFindId(dynamicId);

        if (findDynamicInfo != null) {
            long maxValue = SuccessReleaseOfADynamicConstant.MAX_VALUE;
            String existKey = SuccessReleaseOfADynamicConstant
                    .getSuccessReleaseOfADynamicExistUserIdKey();
            boolean bl = stringRedisTemplate.opsForSet().isMember(existKey, Long.toString(findDynamicInfo.getUserId()));
            log.info("发送动态[{}]，今天是否增加积分达到次数限制[{}]",dynamicId,bl);
            if (!bl) {
                String key = SuccessReleaseOfADynamicConstant
                        .getIntegralSuccessReleaseOfADynamicByUserIdKey(findDynamicInfo.getUserId());
                long num = stringRedisTemplate.opsForValue().increment(key, 1);
                log.info("发送动态[{}],以增加次数[{}]",dynamicId,num);
                if (num <= maxValue) {
                    IntegralRewardsAndPunishmentsType type =
                            IntegralRewardsAndPunishmentsType.SUCCESSFUL_RELEASE_OF_A_DYNAMIC;

                    int flag = userCountDao.updateIntegralSum(findDynamicInfo.getUserId(), type.getIntegralValue());
                    log.info("发送动态[{}],增加积分[{}]",dynamicId,type.getIntegralValue());
                    if (flag == 1) {
                        BillDetailIntegralDTO obj = getBillDetailIntegralDTO(findDynamicInfo.getUserId(), type);
                        billDetailIntegralMq.getBillDetailIntegralMq(obj);
                    }

                    if (num == maxValue) {
                        stringRedisTemplate.opsForSet().add(existKey,Long.toString(findDynamicInfo.getUserId()));
                        stringRedisTemplate.expire(existKey, 2, TimeUnit.DAYS);
                        stringRedisTemplate.expire(key, 2, TimeUnit.DAYS);
                    }
                }
            }
        }

    }

    /**
     * fans
     *
     * @param userId
     */
    public void fansAddBy100(long userId) {
        if (!checkIsHost(userId)) {
            return;
        }
        long maxValue = DiamondsForIntegralBy100RedisKey.FANS_MAX_VALUE;
        String key = DiamondsForIntegralBy100RedisKey.getFandAdd100ByUserIdKey(userId);
        long num = stringRedisTemplate.opsForValue().increment(key, 1);
        if (num >= maxValue) {
            int size = (int) (num / maxValue);
            if (size >= 1) {
                for (int i = 0; i < size; i++) {
                    IntegralRewardsAndPunishmentsType type = IntegralRewardsAndPunishmentsType
                            .FANS_ADD_BY_100;
                    int flag = userCountDao.updateIntegralSum(userId, type.getIntegralValue());
                    if (flag == 1) {
                        BillDetailIntegralDTO obj = getBillDetailIntegralDTO(userId, type);
                        billDetailIntegralMq.getBillDetailIntegralMq(obj);
                        stringRedisTemplate.opsForValue().increment(key, -maxValue);
                    }
                }
            }
        }
    }

    /**
     * 系统奖励与惩罚
     * @param systemRewardsAndPunishmentDTO
     */
    public void getSystemRewardsAndPunishment(SystemRewardsAndPunishmentDTO systemRewardsAndPunishmentDTO){
        IntegralRewardsAndPunishmentsType type = null;
        if(systemRewardsAndPunishmentDTO.getIntegralValue()>0){
            type = IntegralRewardsAndPunishmentsType
                    .SYSTEM_REWARDS;
        }else{
            type = IntegralRewardsAndPunishmentsType
                    .SYSTEM_PUNISHMENT;

        }

        if(type !=null){
            int flag = userCountDao.updateIntegralSum(systemRewardsAndPunishmentDTO.getUserId(),
                    systemRewardsAndPunishmentDTO.getIntegralValue());
            if (flag == 1) {
                BillDetailIntegralDTO obj = getBillDetailIntegralDTO(systemRewardsAndPunishmentDTO.getUserId(),
                        systemRewardsAndPunishmentDTO.getIntegralValue(),type);
                billDetailIntegralMq.getBillDetailIntegralMq(obj);
            }
        }

    }

    /**
     * 构造账单dto
     * @param userId
     * @param type
     * @return
     */
    private BillDetailIntegralDTO getBillDetailIntegralDTO(long userId,
                                                           IntegralRewardsAndPunishmentsType type) {
        BillDetailIntegralMqMessageBuilder mqMessageBuilder = new BillDetailIntegralMqMessageBuilder();
        return mqMessageBuilder.userId(userId)
                .integralRewardsPunishmentsType(type)
                .integralValue(type.getIntegralValue())
                .createDate(LocalDate.now(ZoneOffset.of("+8")))
                .createTime(LocalDateTime.now(ZoneOffset.of("+8")))
                .build();
    }

    /**
     * 构造账单dto
     * @param userId
     * @param integralValue
     * @param type
     * @return
     */
    private BillDetailIntegralDTO getBillDetailIntegralDTO(long userId,int integralValue,
                                                           IntegralRewardsAndPunishmentsType type) {
        BillDetailIntegralMqMessageBuilder mqMessageBuilder = new BillDetailIntegralMqMessageBuilder();
        return mqMessageBuilder.userId(userId)
                .integralRewardsPunishmentsType(type)
                .integralValue(integralValue)
                .createDate(LocalDate.now(ZoneOffset.of("+8")))
                .createTime(LocalDateTime.now(ZoneOffset.of("+8")))
                .build();
    }

    private boolean checkIsHost(long userId) {
        User user = userInfoDao.getUserInfoById(userId);
        if (user == null || user.getIsHost() != 1) {
            return false;
        } else {
            return true;
        }
    }

}
